/***********************************************************************
 *
 * MODULE NAME:    avdtp_core.h
 * PROJECT CODE:   host side stack
 * DESCRIPTION:    Audio/video distribution transport profile
 * MAINTAINER:     Mark Donnelly
 *
 *
 * LICENSE:
 *     This source code is copyright (c) 2008 RDA Ltd.
 *     All rights reserved.
 *
 * REVISION HISTORY:
 * 
 *
 * ISSUES:
 * 
 ***********************************************************************/
#ifndef AVDTP_CORE
#define AVDTP_CORE

#include "host_config.h"
#include "a2dp.h"
#include "host_ctrl.h"


#define A2DP_MAX_SEPS                       4 // sbc and mp3, src and snk

/*! 
	@name Service Categories.

	These are service categories to be used in service capabilities of a Stream
	End Point.
	
*/
/*! \{ */

/*!
	@brief The capability to stream media. This is manditory for advance audio
	distribution profile.
*/
#define AVDTP_SERVICE_MEDIA_TRANSPORT		(1)		
/*!
	@brief The reporting capability. This is not currently supported.
*/
#define AVDTP_SERVICE_REPORTING				(2)		
/*!
	@brief The recovery capability. This is not currently supported.
*/
#define AVDTP_SERVICE_RECOVERY				(3)		
/*!
	@brief The content protection capability. This is not currently supported.
*/
#define AVDTP_SERVICE_CONTENT_PROTECTION	(4)		
/*!
	@brief The header compression capability. This is not currently supported.
*/
#define AVDTP_SERVICE_HEADER_COMPRESSION	(5)		
/*!
	@brief The multiplexing capability. This is not currently supported.
*/
#define AVDTP_SERVICE_MULTIPLEXING			(6)		
/*!
	@brief The codec capability for the Stream End Point.
*/
#define AVDTP_SERVICE_MEDIA_CODEC			(7)		
/*! \} */

/*! 
	@name Service information.

	Used to fill out the fields in a media codec capabilities structure.
*/
/*! \{ */

/*!
	@brief Defines the codec type as audio.
*/
#define AVDTP_MEDIA_TYPE_AUDIO				(0)		
/*!
	@brief Defines the codec type as video.
*/
#define AVDTP_MEDIA_TYPE_VIDEO				(1)		
/*!
	@brief Defines the codec type as multimedia.
*/
#define AVDTP_MEDIA_TYPE_MULTIMEDIA			(2)		
/*!
	@brief Defines the codec as SBC. Manditory to support for A2DP.
*/
#define AVDTP_MEDIA_CODEC_SBC				(0)		
/*!
	@brief Defines the codec as MPEG1/2. Optional to support for A2DP.
*/
#define AVDTP_MEDIA_CODEC_MPEG1_2_AUDIO		(1)		
/*!
	@brief Optional to support.
*/
#define AVDTP_MEDIA_CODEC_MPEG2_4_AAC		(2)		
/*!
	@brief Optional to support.
*/
#define AVDTP_MEDIA_CODEC_ATRAC				(4)		
/*!
	@brief Not supported by a2dp.
*/
#define AVDTP_MEDIA_CODEC_NONA2DP			(0xff)	

/*! \} */

/*! \} */

/*
	Maximum number words needed to contain a
	bit flag for all possible SEID values
*/	
#define NUM_SEID_PACKED_WORDS			(4)

/* Stream Endpoint (SEP) states based on AVDTP Figure 6.4 */
typedef enum
{
	AVDTP_SEP_STATE_EMPTY,
	AVDTP_SEP_STATE_IDLE,
	AVDTP_SEP_STATE_WAITING_FOR_SIGNAL,
	AVDTP_SEP_STATE_DISCOVERING,
	AVDTP_SEP_STATE_READING_CAPS,
	AVDTP_SEP_STATE_PROCESSING_CAPS,
	AVDTP_SEP_STATE_CONFIGURING,	
	AVDTP_SEP_STATE_CONFIGURED,
	AVDTP_SEP_STATE_LOCAL_OPENING,
	AVDTP_SEP_STATE_REMOTE_OPENING,
	AVDTP_SEP_STATE_OPEN,
	AVDTP_SEP_STATE_STREAMING,
	AVDTP_SEP_STATE_LOCAL_SUSPENDING,
	AVDTP_SEP_STATE_LOCAL_CLOSING, 
	AVDTP_SEP_STATE_REMOTE_CLOSING,
	AVDTP_SEP_STATE_RECONFIG_READING_CAPS,
	AVDTP_SEP_STATE_RECONFIG_PROCESSING_CAPS,
	AVDTP_SEP_STATE_RECONFIGURING,
	AVDTP_SEP_STATE_RECONFIGURE_FAILURE,
	AVDTP_SEP_STATE_LOCAL_ABORTING,
	AVDTP_SEP_STATE_REMOTE_ABORTING
}t_SEP_STATE;

/*! 
	@brief A2DP role.
	
	The A2DP specification defines two roles, Source (SRC) and Sink (SNK).  
	
	A device is the SRC when it acts as a source of a digital audio stream that
	is delivered to a SNK on the same Piconet.
	
	A device is the SNK when it acts as a sink of a digital audio stream
	delivered from the SRC on the same Piconet.
*/
typedef enum
{
	/*!  This SEP is a sink. Register the config block dependent on the SEP
	  type (a2dp_sep_type). */
	a2dp_sink,				
	/*! The SEP is an AV source with an USB input for the data. */
	a2dp_source_usb,		
	/*! The SEP is an AV source with an analogue input for the data, using the
	  CSR internal codec. */
	a2dp_source_analogue		
} a2dp_role;


/* Device states */
typedef enum 
{
	AVDTPINITIALISING,
	AVDTPREADY,
	AVDTPPLAYING,
	AVDTPPAUSED
} t_AVDTP_STATE;


/* Stream endpoint state */
typedef struct sep
{
	t_SEP_STATE		state;

	u_int8			seid;
	u_int8			remote_seid;
	u_int16			discovered_seids[NUM_SEID_PACKED_WORDS];	

	t_SEP_STATE			preabort_state;
	u_int16			flush_timeout;
	u_int8			resource_id;
	u_int8	media_type;
	t_SEP_ROLE 		role;
	u_int8			pending_transaction_label;

	u_int8		local_service_caps[10];  //caps size is 10 bytes.
	u_int16			local_service_caps_size;
	u_int8			configured_service_caps[10];
	u_int16			configured_service_caps_size;	

}sep;

typedef struct __AVDTP
{
	//TaskData				task;
	//Task					clientTask; /* Client task id, so we know where to route responses */
	t_AVDTP_STATE	state;
	u_int8			transaction_label;
	u_int16			priority;
	u_int8 	active_seid;
	
	sep   			sep_list_head[A2DP_MAX_SEPS];
       u_int8           sep_count;
	u_int16         signal_cid;
	u_int16         media_cid;
	t_bdaddr      bd_addr;
        u_int8         active_codec_type;
        u_int8          SBC_MAX_Bit_Pool;
    u_int8 start_pos;
    u_int8 end_pos;
    u_int16 offset;
	boolean                 signalling_indications_enabled;
} AVDTP;

void Avdtp_Request_Dispatcher(u_int8* pdu,t_channelId cid, u_int16 packet_size, t_bdaddr bdaddr);
t_SEP_STATE Get_Sep_State(void);

boolean Avdtp_Get_BdAddr(t_bdaddr *addr);
void Avdtp_Handle_Suspend_Req(void);
void Avdtp_Handle_Start_Req(void);
void Avdtp_Handle_Close_Req(void);

const u_int8* Avdtp_Find_Matching_Codec_Specific_Information(const u_int8 *local_caps, const u_int8 *remote_caps, boolean initiating);
boolean Avdtp_Validate_Service_Caps(const u_int8 *caps, u_int16 caps_size, boolean reconfigure, boolean only_check_structure,
								u_int8 *error_category, u_int8 *error_code);
void Avdtp_Change_Sep_State(sep* sep_entry, t_SEP_STATE new_state);
t_api Avdtp_Receive_Data(rdabt_host_buf_t * p_buf);
void Avdtp_Initial(void);

#endif /* AVDTP_CORE */

